#include <QString>
#include "qtest.h"
#include <QSignalSpy>
#include <QVariant>
#include "tst_lightpresetmodeltest.h"

#include "modelViewRules.h"
#include "LightPresetModel.h"
#include "LightPresetData.h"
#include "LightPresetFactory.h"

const int TEST_NUMBER_OF_CHANNELS = 3;

LightPresetModelTest::LightPresetModelTest()
{
}

/**
 * @brief executed before evry test case
 */
void LightPresetModelTest::init()
{
   LightPresetFactory *presetFactory = new LightPresetFactory();
   m_model = new LightPresetModel( TEST_NUMBER_OF_CHANNELS, presetFactory, this);
   m_preset1 = NULL;
   m_preset2 = NULL;
}

/**
 * @brief executed at the end of every test case
 */
void LightPresetModelTest::cleanup()
{
   if (m_preset1 != NULL)
   {
      delete m_preset1;
   }
   if (m_preset2 != NULL)
   {
      delete m_preset2;
   }

   delete m_model;
}

void LightPresetModelTest::creation()
{
   QSignalSpy sig_layoutChanged( m_model, SIGNAL(layoutChanged()) );

   QVERIFY( m_model != NULL );
   QCOMPARE( m_model->rowCount(QModelIndex()), 0);
   QCOMPARE( sig_layoutChanged.length(), 0);
}

void LightPresetModelTest::addOnePreset()
{
   m_preset1 = new LightPresetData( QString("My preset"), 1000,
                                    QList<double>() << 10. << 20. << 30. );

   QSignalSpy sig_layoutChanged( m_model, SIGNAL(layoutChanged()) );
   m_model->updatePreset( *m_preset1 );

   QCOMPARE( m_model->rowCount(QModelIndex()), 1);
   QCOMPARE( sig_layoutChanged.length(), 1);
}

void LightPresetModelTest::removeOnePreset()
{
   m_preset1 = new LightPresetData( QString("My preset"), 1000,
                                    QList<double>() << 10. << 20. << 30. );

   QSignalSpy sig_layoutChanged( m_model, SIGNAL(layoutChanged()) );
   m_model->updatePreset( *m_preset1 );
   m_model->removePreset( *m_preset1 );

   QCOMPARE( m_model->rowCount(QModelIndex()), 0);
   QCOMPARE( sig_layoutChanged.length(), 2);
}

void LightPresetModelTest::getPresetIndex()
{
   m_preset1 = new LightPresetData( QString("My first preset"), 1000,
                                    QList<double>() << 10. << 20. << 30. );
   m_preset2 = new LightPresetData( QString("My second preset"), 1000,
                                    QList<double>() << 10. << 20. << 30. );

   m_model->updatePreset( *m_preset1 );
   m_model->updatePreset( *m_preset2 );
   QModelIndex index = m_model->searchByName( QString("My second preset") );

   QVERIFY( index != QModelIndex());
   const LightPresetData *readPreset;
   readPreset = m_model->data( index, modelViewRules::Binary).value<const LightPresetData *>();
   QVERIFY(readPreset != NULL);

   QCOMPARE( readPreset->name(), QString("My second preset"));
   QCOMPARE( readPreset->fadeTime(), 1000 );
   QCOMPARE( readPreset->levelList(), QList<double>() << 10. << 20. << 30. );
}

void LightPresetModelTest::addPresetAlreayExisting()
{
   m_preset1 = new LightPresetData( QString("My preset"), 1000,
                                    QList<double>() << 10. << 20. << 30. );
   m_preset2 = new LightPresetData( QString("My preset"), 2000,
                                    QList<double>() << 40. << 50. << 60. );

   QSignalSpy sig_layoutChanged( m_model, SIGNAL(layoutChanged()) );
   m_model->updatePreset( *m_preset1 );
   m_model->updatePreset( *m_preset2 );

   /* m_preset2 overwrites data of preset1 */
   QCOMPARE( m_model->rowCount(QModelIndex()), 1);

   const LightPresetData *readPreset;
   readPreset = m_model->data( m_model->index(0), modelViewRules::Binary).value<const LightPresetData *>();
   QVERIFY(readPreset != NULL);

   QCOMPARE( readPreset->fadeTime(), 2000);
   QCOMPARE( readPreset->levelList(), QList<double>() << 40. << 50. << 60. );
   QCOMPARE( sig_layoutChanged.length(), 2);
}

void LightPresetModelTest::removeUnexistingPreset()
{
   m_preset1 = new LightPresetData( QString("My preset"), 1000,
                                    QList<double>() << 10. << 20. << 30. );

   /* preset is not added */
   QSignalSpy sig_layoutChanged( m_model, SIGNAL(layoutChanged()) );

   m_model->removePreset( *m_preset1);
   /* expected result: just nothing is done */
   QCOMPARE( sig_layoutChanged.length(), 0);
}

void LightPresetModelTest::getInvalidPresetIndex()
{
   QModelIndex index = m_model->searchByName( QString("Unexisting label") );
   QCOMPARE( index, QModelIndex());
}

void LightPresetModelTest::retrieveDataFromWrongIndex()
{
   const LightPresetData *preset;
   bool exceptionCought = false;

   /* row 1 does not exist */
   try
   {
      preset = m_model->data( m_model->index(1,0), Qt::DisplayRole).value<const LightPresetData *>();
   }
   catch( QString &msg)
   {
      exceptionCought = true;
      QCOMPARE( msg, QString("retriving data from invalid index"));
   }

   QVERIFY( exceptionCought == true );
}


